perf(database): index EnvironmentVariableValue.valueReferenceId so secret deletes stop seq-scanning - #4555
Conversation
…cret deletes stop seq-scanning
|
WalkthroughAdded an index on 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Why this change
EnvironmentVariableValue.valueReferenceis anonDelete: SetNullforeign key. Deleting aSecretReference(the env var edit/delete path for secret values) fires the cascadeUPDATE ONLY "EnvironmentVariableValue" SET "valueReferenceId" = NULL WHERE $1 = "valueReferenceId". That cascade is scan-shaped: with no index onvalueReferenceId, it reads the entire table to find the rows referencing the deleted secret. The parentSecretReferencedelete does almost no work itself; its latency is dominated by this cascade.Diagnosis
EnvironmentVariableValuewas indexed onenvironmentIdand(variableId, environmentId), but not onvalueReferenceId. The SET NULL cascade therefore did a full sequential scan of the whole table. Two sibling SET NULL cascades on the same delete (OrganizationIntegration.tokenReferenceId,User.mfaSecretReferenceId) are index-backed and stay fast, which isolates the missing index as the cause.Change
Add
@@index([valueReferenceId])onEnvironmentVariableValue, created withCREATE INDEX CONCURRENTLY IF NOT EXISTSsoprisma migrate deploystays safe on a live table.Benchmark (local, seeded)
Local Postgres seeded with 1,000,000
EnvironmentVariableValuerows,EXPLAIN (ANALYZE, BUFFERS)on the SET NULL cascade with zero matching rows (the worst case: reads the whole table, affects nothing):In a variant where the secret matched several thousand rows, the parent
SecretReferencedelete'sEnvironmentVariableValue_valueReferenceId_fkeytrigger dropped from 216 ms to 88 ms (the residual is the heap work of nulling those rows).Expected impact
The cascade drops from a full-table sequential scan to a targeted index lookup. The win grows with the table, so the benefit is larger than the seeded numbers above.
Risks
EnvironmentVariableValuewrites; small, single-column, and it should be pre-created before the migration deploys (per the repo index rules).Companion to the same fix on
ProjectAlert.channelId.